In [1]:
    
import sys; sys.path.append('../..')
from puzzles import leet_puzzle
leet_puzzle('valid-number')
    
    
In [2]:
    
def is_number(input_string):
    """
    Determine if the input_string is a valid number or not, for example:
    
    >>> is_number("0.1")
    True
    >>> is_number("abc")
    False
    - Numbers in scientific notation are allowed.
    - Only '.' as decimal point is accepted.
    - No thousands separators are allowed.
    
    :param input_string: The input string to check.
    
    :return: True if input_string is a valid number, otherwise False.
    """
    input_string = input_string.strip(' ')
    
    if input_string in ('.', ''):
        return False
    
    input_string = input_string.lstrip('+-')
    
    last_is_digit = False
    had_decimal_point = False
    had_e = False
    last = len(input_string) - 1
    
    for i, c in enumerate(input_string):
    
        # process allowed non digit characters
    
        if c == 'e':
            # 'e' is only valid if it is not the last character
            # there is only one occurence, and it must follow a digit
            if i == last or had_e or not last_is_digit:
                return False
            had_e = True
        
        elif c == '.':
            # decimal point is only valid if we didn't already have
            # a scientific notation character, and it is the only
            # decimal point
            if had_decimal_point or had_e:
                return False
            had_decimal_point = True
        
        elif c in ('+', '-'):
            # + / - is only valid when not the first character if
            # it occurs as part of scientific notation.
            if last_c != 'e':
                return False 
        
        elif not c.isdigit():
            return False
        
        else:
            last_is_digit = True
            
        last_c = c
            
    return True
def is_number_using_float(input_string):
    try:
        float(input_string)
    except ValueError:
        return False
    return True
            
test_cases = [
    "", "0", "0.1", " 0.1", "abc", "4e10", "4.5e10", "4.5e10e10",
    "-4", "+4", " ", "...", ".0.0.0.", "1.abc", "e", "10e", "1e2",
    ".31", " . ", ".", "x.y.z", "2.4.6", ".1", "1.", "..1", "1..",
    "6e6.6", "0042032e+6", "0042032e6+6", "+.1", "-1.", "..1", "1..", 
    "1+", "1-", "1 2 3 4 ", "1.2 3", ".1.2.3.", "_123", " e ", ".e",
    "1,345,344.00"
]
for test_case in test_cases:
    actual = is_number(test_case)
    expected = is_number_using_float(test_case)
    if actual != expected:
        assert False, ('is_number("' + test_case + '") == ' + 
                       str(actual) + ' != ' + str(expected))
        
print str(len(test_cases)) + ' tests passed'
    
    
In [3]:
    
%%timeit
is_number("0.34834")
    
    
In [4]:
    
%%timeit
is_number_using_float("0.34834")
    
    
The timings here demonstrate that it really isn't worth implementing your own float to string function. Best just used the build in conversion which probably uses optimised c code.